package cn.wolfcode.wolf2w.business.service.impl;

import cn.wolfcode.wolf2w.business.api.RemoteDestinationService;
import cn.wolfcode.wolf2w.business.api.domain.*;
import cn.wolfcode.wolf2w.business.mapper.StrategyCatalogMapper;
import cn.wolfcode.wolf2w.business.mapper.StrategyContentMapper;
import cn.wolfcode.wolf2w.business.mapper.StrategyMapper;
import cn.wolfcode.wolf2w.business.mapper.StrategyThemeMapper;
import cn.wolfcode.wolf2w.business.query.StrategyQuery;
import cn.wolfcode.wolf2w.business.service.IStrategyService;
import cn.wolfcode.wolf2w.business.util.DateUtil;
import cn.wolfcode.wolf2w.common.core.constant.SecurityConstants;
import cn.wolfcode.wolf2w.common.core.context.SecurityContextHolder;
import cn.wolfcode.wolf2w.common.redis.service.RedisService;
import cn.wolfcode.wolf2w.common.redis.util.RedisKeys;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 攻略Service业务层处理
 * 
 * @author fang
 * @date 2024-09-27
 */
@Service
@Transactional
public class StrategyServiceImpl extends ServiceImpl<StrategyMapper, Strategy> implements IStrategyService {

    @Autowired
    private StrategyContentMapper strategyContentMapper;

    @Autowired
    private StrategyCatalogMapper strategyCatalogMapper;

    @Autowired
    private StrategyThemeMapper strategyThemeMapper;

    @Autowired
    private RemoteDestinationService remoteDestinationService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AmqpTemplate amqpTemplate;



    @Override
    public IPage<Strategy> queryPage(StrategyQuery qo) {
        IPage<Strategy> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        QueryWrapper<Strategy> qw = new QueryWrapper<>();
        qw.orderByDesc(qo.getOrderBy());
        if (qo.getType() != null){
            if(1==qo.getType() || 2==qo.getType()){
                qw.eq("dest_id",qo.getRefid());
            }else if (3 == qo.getType()){
                qw.eq("theme_id",qo.getRefid());
            }
        }

        return baseMapper.selectPage(page,qw);
/*        return lambdaQuery()
                .page(page);*/
    }

    @Override
    public List<Strategy> queryViewnumTop3(Long destId) {
        List<Strategy> list = lambdaQuery().eq(Strategy::getDestId, destId)
                .orderByDesc(Strategy::getViewnum)
                .last("limit 3")
                .list();
        return list;
    }

    @Override
    public Strategy selectById(Long id) {
        StrategyContent strategyContent = strategyContentMapper.selectById(id);
        Strategy strategy = baseMapper.selectById(id);
        strategy.setContent(strategyContent);
        return strategy;
    }

    @Override
    public int insert(Strategy strategy) {

        StrategyCatalog strategyCatalog = strategyCatalogMapper.selectById(strategy.getCatalogId());
        strategy.setDestId(strategyCatalog.getDestId());
        strategy.setDestName(strategyCatalog.getDestName());
        strategy.setCatalogName(strategyCatalog.getName());

        StrategyTheme theme = strategyThemeMapper.selectById(strategy.getThemeId());
        strategy.setThemeName(theme.getName());
        strategy.setCreateTime(new Date());

        // TODO: 2024/9/30 矫正isborad
        List<Destination> toasts = remoteDestinationService.getToasts(strategy.getDestId(), SecurityConstants.INNER).getData();
        Destination destination = toasts.get(0);
        if (destination.getName().equals("中国")){
            strategy.setIsabroad(0L);
        }else{
            strategy.setIsabroad(1L);
        }

        strategy.setViewnum(0L);
        strategy.setReplynum(0L);
        strategy.setFavornum(0L);
        strategy.setSharenum(0L);
        strategy.setThumbsupnum(0L);
        baseMapper.insert(strategy);
        Long id = strategy.getId();
        String content = strategy.getContent().getContent();
        StrategyContent strategyContent = new StrategyContent(id, content);
        strategyContentMapper.insert(strategyContent);

        //优化数据
        Strategy strategyMQ = new Strategy();
        strategyMQ.setId(strategy.getId());
        strategyMQ.setTitle(strategy.getTitle());
        strategyMQ.setSubTitle(strategy.getSubTitle());
        strategyMQ.setSummary(strategy.getSummary());
        amqpTemplate.convertAndSend("strategyExchange","", JSON.toJSONString(strategyMQ));



        return 1;
    }

    //点击后阅读量加一
    @Override
    public Map<String, Object> viewnumIncr(Long sid) {
        String join = strategyHashInit(sid);
        //阅读量加一
        redisService.incrementCacheMapValue(join,"viewnum",1);
        //查询后的数据进行翻查
        return redisService.getCacheMap(join);
    }

    @Override
    public Map<String, Object> replynumIncr(Long sid) {
        String join = strategyHashInit(sid);
        //回复数加一
        redisService.incrementCacheMapValue(join,"replynum",1);
        //查询后的数据进行翻查
        return redisService.getCacheMap(join);
    }

    @Override
    public Map<String, Object> favornumIncr(Long sid) {
        //先判断是收藏还是取消收藏
        Long userId = SecurityContextHolder.getUserId();
        //评出来一个key
        String key = RedisKeys.USER_STRATEGY_FAVOR.join(userId.toString());
        if (!redisService.hasKey(key)){
            //没有key
            Set<Long> sids = new HashSet<>();
            sids.add(-1L);
            //set至少有一个数据，redis会直接清除空数据，所以需要添加一个新数据
            redisService.setCacheSet(key,sids);

        }

        //文章的key
        String statisKey = RedisKeys.STRATEGY_STATIS_HASH.join(sid.toString());
        boolean result = false;
        //是否包含
        boolean cacheSetContains = redisService.isCacheSetContains(key, sid);
        if (!cacheSetContains){
            //收藏操作
            redisService.incrementCacheMapValue(statisKey,"favornum",1);
            //改变状态
            redisService.addCacheSetValue(key,sid);
            result = true;
        }else {
            //取消收藏
            redisService.incrementCacheMapValue(statisKey,"favornum",-1);
            redisService.deleteCacheSetValue(key,sid);
        }
        //查回来map
        Map<String, Object> map = redisService.getCacheMap(statisKey);
        map.put("result",result);
        return map;
    }

    @Override
    public Map<String, Object> thumbsubIncr(Long sid) {

        //用户key 和  攻略 key
        Long uid = SecurityContextHolder.getUserId();
        //可变传参
        String key = RedisKeys.USER_STRATEGY_THUMBSUP.join(sid.toString(), uid.toString());
        //加减的key,统计数据的key，和普通的key
        String statisKey = RedisKeys.STRATEGY_STATIS_HASH.join(sid.toString());

        if (!redisService.hasKey(key)) {
            Date now = new Date();
            Date end = DateUtil.getEndDate(now);
            Long dateBetween = DateUtil.getDateBetween(now, end);
            dateBetween = dateBetween == 0 ? 1 : dateBetween;
            //没有key的时候，100是过期时间
            redisService.setCacheObject(key,0,dateBetween, TimeUnit.SECONDS);
        }
        //自己点赞数
        Long ret = redisService.incrementCacheObjectValue(key, 1);
        boolean result = true;
        if (ret > 5) {
            //友好提示
            result = false;
        }else{
            //文章总点赞数
            redisService.incrementCacheMapValue(statisKey,"thumbsupnum",1);
        }
        Map<String, Object> cacheMap = redisService.getCacheMap(statisKey);
        cacheMap.put("result",result);
        return cacheMap;
    }

    @Override
    public void statisHashPersistence() {
        // System.out.println(1122333);
        String searchKeys = RedisKeys.STRATEGY_STATIS_HASH.join("*");
        Collection<String> keys = redisService.keys(searchKeys);
        for (String key : keys) {
            Map<String, Object> cacheMap = redisService.getCacheMap(key);
            //更新操作
            Strategy strategy = new Strategy();
            strategy.setViewnum(Long.valueOf(cacheMap.get("viewnum").toString()));
            strategy.setReplynum(Long.valueOf(cacheMap.get("replynum").toString()));
            strategy.setSharenum(Long.valueOf(cacheMap.get("sharenum").toString()));
            strategy.setFavornum(Long.valueOf(cacheMap.get("favornum").toString()));
            strategy.setThumbsupnum(Long.valueOf(cacheMap.get("thumbsupnum").toString()));
            LambdaUpdateWrapper<Strategy> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(Strategy::getId,cacheMap.get("id"));
            baseMapper.update(strategy,lambdaUpdateWrapper);
        }

    }

    @Override
    public void initStrategyStatisHash() {
        //查询所有，目前阶段使用查询所有
        // 数据较大，条件查询，数据较小，查询所有（主要存放热点信息）
        List<Strategy> list = baseMapper.selectList(null);
        for (Strategy strategy : list) {
            //每个文章的key
            String join = RedisKeys.STRATEGY_STATIS_HASH.join(strategy.getId().toString());
            if(!redisService.hasKey(join)){
                Map<String,Object> map = new HashMap<>();
                map.put("viewnum",Integer.valueOf(strategy.getViewnum().toString()));
                map.put("replynum",Integer.valueOf(strategy.getReplynum().toString()));
                map.put("favornum",Integer.valueOf(strategy.getFavornum().toString()));
                map.put("sharenum",Integer.valueOf(strategy.getSharenum().toString()));
                map.put("thumbsupnum",Integer.valueOf(strategy.getThumbsupnum().toString()));
                //数据的标识
                map.put("id",strategy.getId());
                redisService.setCacheMap(join,map);
            }

        }

    }

    private String strategyHashInit(Long sid){
        String join = RedisKeys.STRATEGY_STATIS_HASH.join(sid.toString());
        if (!redisService.hasKey(join)) {
            //没有key，那么需要初始一个key
            Strategy strategy = baseMapper.selectById(sid);
            Map<String,Object> map = new HashMap<>();
            map.put("viewnum",Integer.valueOf(strategy.getViewnum().toString()));
            map.put("replynum",Integer.valueOf(strategy.getReplynum().toString()));
            map.put("favornum",Integer.valueOf(strategy.getFavornum().toString()));
            map.put("sharenum",Integer.valueOf(strategy.getSharenum().toString()));
            map.put("thumbsupnum",Integer.valueOf(strategy.getThumbsupnum().toString()));
            //数据的标识
            map.put("id",strategy.getId());
            redisService.setCacheMap(join,map);
        }
        return join;
    }
}
